

#include "studio_macros.h"
#include "file/studio_dir.h"
#include "time/studio_time.h"
#include "string/studio_str_algo.h"
#include "string/studio_regex.h"
#include "time/studio_timer.h"
#include "system/background.h"
#include "singleton/studio_singleton.h"
#include "geography/studio_proj.h"





#pragma pack(1)

#include <iostream>
#include <iomanip>
#include <vector>

const uint32_t vvl40_head_common_net = 0xFEFFFEFF;

inline uint16_t calculate_checksum_host(const uint8_t* data, int length)
{
    uint32_t sum = 0;
    for (int i = 0; i < length; ++i)
    {
        sum += data[i];
    }
    // 处理进位
    while (sum >> 16)
    {
        sum = (sum & 0xFFFF) + (sum >> 16);
    }
    return static_cast<uint16_t>(sum);
}

template <typename T>
bool inline verify_checksum_16(const T& raw)
{
    uint16_t checksum_expected_net = htons(calculate_checksum_host((uint8_t*)&raw, sizeof(raw) - sizeof(raw.checksum)));
    uint16_t checksum_received_net = raw.checksum;
    return checksum_expected_net == checksum_received_net;
};


struct resp_vvl40_net
{
    uint32_t head = vvl40_head_common_net;  // 0-3: 固定帧头
    uint16_t compass = 0;                   // 4-5: 指南针角度 / 10.0
    uint8_t pitch_dir = 0;                  // 6: 前倾(0) / 后倾(1)
    uint16_t pitch_value = 0;               // 7-8 : 前后倾角度 / 10.0
    uint8_t roll_state = 0;                 // 9: 左倾(0) / 右倾(1)
    uint16_t roll_value = 0;                // 10-11: 左右倾角度 / 10.0
    uint16_t camera_angle = 0;              // 12-13: 摄像头云台角度，45 - 接收值
    uint16_t sonar_angle = 0;               // 14-15: 声呐上下角度，45 - 接收值
    uint16_t height_m = 0.0f;               // 16-17: 高度 0.00米
    int32_t depth_m = 0.0f;                 // 18-21: 深度(米)，float 类型
    int16_t water_temp;                     // 22-23: 水温 / 10，负数+10000，高字节在前
    int16_t cabin_temp;                     // 24-25: 仓温 / 10，负数+10000，高字节在前
    uint16_t cabin_humidity;                // 26-27: 仓湿度 / 10，高字节在前
    uint8_t water_leak;                     // 28: 漏水检测 >100 表示漏水
    uint8_t depth_zero_flag;                // 29: 深度清零标志，1=已清零
    uint16_t front_left_thruster_current;   // 30-31: 前左推进器电流
    uint16_t front_right_thruster_current;  // 32-33: 前右推进器电流
    uint16_t rear_left_thruster_current;    // 34-35: 后左推进器电流
    uint16_t rear_right_thruster_current;   // 36-37: 后右推进器电流
    uint16_t vertical_rear_left_current;    // 38-39: 升降后左电流
    uint16_t vertical_rear_right_current;   // 40-41: 升降后右电流
    uint16_t vertical_front_left_current;   // 42-43: 升降前左电流
    uint16_t vertical_front_right_current;  // 44-45: 升降前右电流

    uint16_t checksum;  // 46-47: 累加和校验(高位在前)，计算前46字节
};

struct resp_vvl40_host
{
    uint32_t head = vvl40_head_common_net;  // 0-3: 固定帧头
    float compass = 0.0f;                       // 4-5: 指南针角度 / 10.0
    uint8_t pitch_dir = 0;                      // 6: 前倾(0) / 后倾(1)
    float pitch_value = 0.0f;                   // 7-8: 前后倾角度 / 10.0
    uint8_t roll_state = 0;                     // 9: 左倾(0) / 右倾(1)
    float roll_value = 0.0f;                    // 10-11: 左右倾角度 / 10.0
    float camera_angle = 0.0f;                  // 12-13: 摄像头云台角度，45 - 接收值
    float sonar_angle = 0.0f;                   // 14-15: 声呐上下角度，45 - 接收值
    float height_m = 0.0f;                      // 16-17: 高度 0.00米
    float depth_m = 0.0f;                       // 18-21: 深度(米)，float 类型
    float water_temp = 0.0f;                    // 22-23: 水温 / 10，负数+10000
    float cabin_temp = 0.0f;                    // 24-25: 仓温 / 10，负数+10000
    float cabin_humidity = 0.0f;                // 26-27: 仓湿度 / 10
    uint8_t water_leak = 0;                     // 28: 漏水检测 >100 表示漏水
    uint8_t depth_zero_flag = 0;                // 29: 深度清零标志，1=已清零
    uint16_t front_left_thruster_current = 0;   // 30-31: 前左
    uint16_t front_right_thruster_current = 0;  // 32-33: 前右
    uint16_t rear_left_thruster_current = 0;    // 34-35: 后左
    uint16_t rear_right_thruster_current = 0;   // 36-37: 后右
    uint16_t vertical_rear_left_current = 0;    // 38-39: 升降后左
    uint16_t vertical_rear_right_current = 0;   // 40-41: 升降后右
    uint16_t vertical_front_left_current = 0;   // 42-43: 升降前左
    uint16_t vertical_front_right_current = 0;  // 44-45: 升降前右

};

// 将数据转换为字节数组，并计算校验和
void calculate_and_set_checksum(resp_vvl40_net& net_data)
{
    // 计算前46字节的校验和
    uint8_t* data_ptr = reinterpret_cast<uint8_t*>(&net_data);
    int length = sizeof(net_data) - sizeof(net_data.checksum);
    uint16_t checksum = calculate_checksum_host(data_ptr, length);

    // 将校验和填入结构体（网络字节序）
    net_data.checksum = htons(checksum);
}

inline void modbus_float_ntoh(const uint32_t& net, float& host)
{
    std::memcpy(&host, &net, sizeof(float));
}
// 打印数据为16进制字符串
void print_hex(const uint8_t* data, int length)
{
    for (int i = 0; i < length; ++i)
    {
        std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)data[i] << " ";
    }
    std::cout << std::dec << std::endl;
}

void inline resp_vvl40_hton(const resp_vvl40_host& host, resp_vvl40_net& net)
{
    net.head = vvl40_head_common_net;
    net.compass = htons(static_cast<uint16_t>(host.compass * 10.0f));
    net.pitch_dir = host.pitch_dir;
    net.pitch_value = htons(static_cast<uint16_t>(host.pitch_value * 10.0f));
    net.roll_state = host.roll_state;
    net.roll_value = htons(static_cast<uint16_t>(host.roll_value * 10.0f));
    net.camera_angle = htons(static_cast<uint16_t>(host.camera_angle));
    net.sonar_angle = htons(static_cast<uint16_t>(host.sonar_angle));
    net.height_m = htons(static_cast<uint16_t>(host.height_m * 100.0f));
    net.depth_m = htonl(static_cast<uint32_t>(host.depth_m));
    net.water_temp = htons(static_cast<int16_t>(host.water_temp * 10.0f));
    net.cabin_temp = htons(static_cast<int16_t>(host.cabin_temp * 10.0f));
    net.cabin_humidity = htons(static_cast<uint16_t>(host.cabin_humidity * 10.0f));
    net.water_leak = host.water_leak;
    net.depth_zero_flag = host.depth_zero_flag;

    net.front_left_thruster_current = htons(host.front_left_thruster_current);
    net.front_right_thruster_current = htons(host.front_right_thruster_current);
    net.rear_left_thruster_current = htons(host.rear_left_thruster_current);
    net.rear_right_thruster_current = htons(host.rear_right_thruster_current);
    net.vertical_rear_left_current = htons(host.vertical_rear_left_current);
    net.vertical_rear_right_current = htons(host.vertical_rear_right_current);
    net.vertical_front_left_current = htons(host.vertical_front_left_current);
    net.vertical_front_right_current = htons(host.vertical_front_right_current);
}

void print_structure_info(const resp_vvl40_net& net_data)
{
    std::cout << "Structure field information:" << std::endl;
    std::cout << "Head: 0x" << std::hex << net_data.head << std::dec << std::endl;
    std::cout << "Compass: " << ntohs(net_data.compass) << std::endl;
    std::cout << "Pitch dir: " << (int)net_data.pitch_dir << std::endl;
    std::cout << "Pitch value: " << ntohs(net_data.pitch_value) << std::endl;
    std::cout << "Roll state: " << (int)net_data.roll_state << std::endl;
    std::cout << "Roll value: " << ntohs(net_data.roll_value) << std::endl;
    std::cout << "Camera angle: " << ntohs(net_data.camera_angle) << std::endl;
    std::cout << "Sonar angle: " << ntohs(net_data.sonar_angle) << std::endl;
    std::cout << "Height: " << ntohs(net_data.height_m) << std::endl;

    // 深度转换回float
    uint32_t depth_net = ntohl(net_data.depth_m);
    float depth_float;
    std::memcpy(&depth_float, &depth_net, sizeof(float));
    std::cout << "Depth: " << depth_float << std::endl;

    std::cout << "Water temp: " << ntohs(net_data.water_temp) << std::endl;
    std::cout << "Cabin temp: " << ntohs(net_data.cabin_temp) << std::endl;
    std::cout << "Cabin humidity: " << ntohs(net_data.cabin_humidity) << std::endl;
    std::cout << "Water leak: " << (int)net_data.water_leak << std::endl;
    std::cout << "Depth zero flag: " << (int)net_data.depth_zero_flag << std::endl;
    std::cout << "Checksum: 0x" << std::hex << ntohs(net_data.checksum) << std::dec << std::endl;
}

//void inline resp_vvl40_ntoh(const resp_vvl40_net& net, resp_vvl40_host& host)
//{
//    host.compass = static_cast<float>(ntohs(net.compass)) * 0.1f;
//    host.pitch_dir = net.pitch_dir;
//    host.pitch_value = static_cast<float>(ntohs(net.pitch_value)) * 0.1f;
//    host.roll_state = net.roll_state;
//    host.roll_value = static_cast<float>(ntohs(net.roll_value)) * 0.1f;
//    host.camera_angle = static_cast<float>(ntohs(net.camera_angle));
//    host.sonar_angle = static_cast<float>(ntohs(net.sonar_angle));
//    host.height_m = static_cast<float>(ntohs(net.height_m)) * 0.01f;
//
//    // 深度是 float，直接 memcpy（注意网络字节序是 big-endian，float 可能需要额外处理）
//    uint32_t depth_net;
//    std::memcpy(&depth_net, &net.depth_m, sizeof(depth_net));
//    modbus_float_ntoh(depth_net, host.depth_m);
//
//    host.water_temp = static_cast<float>(ntohs(net.water_temp)) * 0.1f;
//    host.cabin_temp = static_cast<float>(ntohs(net.cabin_temp)) * 0.1f;
//    host.cabin_humidity = static_cast<float>(ntohs(net.cabin_humidity)) * 0.1f;
//    host.water_leak = net.water_leak;
//    host.depth_zero_flag = net.depth_zero_flag;
//
//    host.front_left_thruster_current = ntohs(net.front_left_thruster_current);
//    host.front_right_thruster_current = ntohs(net.front_right_thruster_current);
//    host.rear_left_thruster_current = ntohs(net.rear_left_thruster_current);
//    host.rear_right_thruster_current = ntohs(net.rear_right_thruster_current);
//    host.vertical_rear_left_current = ntohs(net.vertical_rear_left_current);
//    host.vertical_rear_right_current = ntohs(net.vertical_rear_right_current);
//    host.vertical_front_left_current = ntohs(net.vertical_front_left_current);
//    host.vertical_front_right_current = ntohs(net.vertical_front_right_current);
//}
#pragma pack()

int main()
{
    int size = sizeof(resp_vvl40_net);
    // 在主函数中给结构体每个字段赋值
    resp_vvl40_host host_data;
    host_data.compass = 90.1f;                       // 指南针角度
    host_data.pitch_dir = 0;                        // 前倾(0) / 后倾(1)
    host_data.pitch_value = -15.0f;                   // 前后倾角度
    host_data.roll_state = 0;                       // 左倾(0) / 右倾(1)
    host_data.roll_value = 10.0f;                   // 左右倾角度
    host_data.camera_angle = 20.0f;                 // 摄像头云台角度
    host_data.sonar_angle = 15.0f;                  // 声呐上下角度
    host_data.height_m = 150.0f;                    // 高度
    host_data.depth_m = 260.0f;                     // 深度
    host_data.water_temp = 31.0f;                   // 水温
    host_data.cabin_temp = 25.0f;                   // 仓温
    host_data.cabin_humidity = 50.0f;               // 仓湿度
    host_data.water_leak = 1;                       // 漏水检测
    host_data.depth_zero_flag = 1;                  // 深度清零标志
    host_data.front_left_thruster_current = 1000;   // 前左
    host_data.front_right_thruster_current = 1001;  // 前右
    host_data.rear_left_thruster_current = 1002;    // 后左
    host_data.rear_right_thruster_current = 1003;   // 后右
    host_data.vertical_rear_left_current = 1004;    // 升降后左
    host_data.vertical_rear_right_current = 1005;   // 升降后右
    host_data.vertical_front_left_current = 1006;   // 升降前左
    host_data.vertical_front_right_current = 1007;  // 升降前右

    // 计算校验和并将其填入结构体
    resp_vvl40_net net_data;
    resp_vvl40_hton(host_data, net_data);

    // 计算并设置校验和
    calculate_and_set_checksum(net_data);

    // 打印结构体信息
    print_structure_info(net_data);

    // 将数据转为字节数组并打印16进制
    uint8_t* data_ptr = reinterpret_cast<uint8_t*>(&net_data);
    int length = sizeof(net_data);

    print_hex(data_ptr, length);

    // 验证校验和
    if (verify_checksum_16(net_data))
    {
        std::cout << "Checksum verification: PASSED" << std::endl;
    }
    else
    {
        std::cout << "Checksum verification: FAILED" << std::endl;
    }

    return 0;
}


//根据上面的代码 我现在希望根据实现的resp_vvl40_host 结构体，实现一个resp_vvl40_net结构体, 然后把 resp_vvl40_net 包含其中的头部和校验位以16进制打印输出

//int main()
//{
//    // 你的模拟数据（前46字节）
//    //std::vector<uint8_t> data = {
//    //    0xFF, 0xFE, 0xFF, 0xFE, 0x04, 0xD2, 0x01, 0x00, 0x96, 0x01, 0x00, 0x64, 0x0F, 0x00, 0x19, 0x00, 0x00, 0x96, 0x02, 0x08, 0x00, 0xFF, 0x01,
//    //    0x18, 0x02, 0x58, 0x01, 0x01, 0x64, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0x00  // 前46字节
//    //};
//
//    resp_vvl40_host temp_resp;
//    temp_resp.compass = 10.0;
//
//    // 计算校验和
//    uint16_t checksum = calculate_checksum_host(data.data(), data.size());
//
//    std::cout << "Calculated checksum: 0x" << std::hex << std::setw(4) << std::setfill('0') << checksum << std::dec << std::endl;
//
//    // 输出完整的正确数据
//    std::cout << "Complete correct data:" << std::endl;
//    for (size_t i = 0; i < data.size(); ++i)
//    {
//        std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(data[i]) << " ";
//        if ((i + 1) % 16 == 0)
//            std::cout << std::endl;
//    }
//    // 添加校验和（网络字节序：高位在前）
//    std::cout << std::hex << std::setw(2) << std::setfill('0') << ((checksum >> 8) & 0xFF) << " ";
//    std::cout << std::hex << std::setw(2) << std::setfill('0') << (checksum & 0xFF) << std::dec << std::endl;
//
//    return 0;
//}















/////////////////  计算方位角和距离  //////////////////////
//  int main(int argc, char* argv[])
// {
//      silly::geo::utils::init_gdal_env();
//
//      //娄底市字下边, 111.6062, 27.6885 湘潭市字的上边 112.5991, 27.7669
//      double lon_form = 111.6062;
//      double lat_form = 27.6885;
//
//      double lon_to = 112.5991;
//      double lat_to = 27.7669;
//
//
//      std::vector<studio_geo_coll> collections;
//      studio_geo_coll temp;
//      temp.m_type = enum_geometry_type::egtMultiPoint;
//      temp.m_points.push_back(studio_point(lon_form, lat_form));
//      temp.m_points.push_back(studio_point(lon_to, lat_to));
//      collections.push_back(temp);
//      silly::geo::utils::write_geo_coll("../../../../data/geojson/distance_azimuth.geojson", collections);
//
//
//      double central = static_cast<int>(lon_form / 3) * 3;
//
//      proj proj_test;
//      // 转高斯投影
//      double gx_form = 0.0;
//      double gy_form = 0.0;
//      proj_test.lonlat_to_gauss(central, lon_form, lat_form, gx_form, gy_form);
//      // 转高斯投影
//      double gx_to = 0.0;
//      double gy_to = 0.0;
//      proj_test.lonlat_to_gauss(central, lon_to, lat_to, gx_to, gy_to);
//
//      // 两点间距离
//      double distance = std::sqrt(std::pow(gx_form - gx_to, 2) + std::pow(gy_form - gy_to, 2));
//
//      // 方位角
//      // 输入：高斯投影坐标 (gx_form, gy_form) 和 (gx_to, gy_to)
//      double delta_x = gx_to - gx_form;
//      double delta_y = gy_to - gy_form;
//      // 计算方位角（弧度）
//      double theta_rad = std::atan2(delta_x, delta_y);
//
//      // 转换为度数并调整范围
//      double theta_deg = theta_rad * (180.0 / M_PI);
//      if (theta_deg < 0)
//      {
//          theta_deg += 360.0;
//      }
//
//      std::cout << "Distance: " << std::to_string(distance) << " m" << std::endl;
//      std::cout << "Bearing: " << std::to_string(theta_deg) << " degrees" << std::endl;
//
//
//      silly::geo::utils::destroy_gdal_env();
//      return 0;
//  }

//// 查询进行 关闭进程
// int main(int argc, char* argv[])
//{
//     studio_background background;
//     background.getAllPrj();
//     background.stopPrj("./TzxTopoWeb");
//
//	return 0;
// }

// int main(int argc, char* argv[])
//{
//     studio_timer timer;
//     std::string dataDir = DEFAULT_AO_DATA_DIR;
//     std::string input_txt = dataDir + "/txt/2003003.txt";
//
//     std::ifstream inFile;
//     inFile.open(input_txt);
//     if (!inFile.is_open())
//     {
//         std::cout << "Failed to open TXT file." << std::endl;
//         return false;
//     }
//
//     // 记录当前文件指针位置
//     std::streampos originalPos = inFile.tellg();
//     std::vector<float> data;
//     // 检测文件是否包含元数据头部
//     std::string firstLine;
//     while (std::getline(inFile, firstLine))
//     {
//         std::cout << "firstLine: " << firstLine << std::endl;
//         std::vector<std::string> onceLine = studio_str_algo::separate(firstLine, "     ");
//
//         int b = 0;
//     }
//     inFile.close();
//
//
//     timer.timed_print();
//
//
//     return 0;
//
//     //std::string inputDate1 = "2023-07-24 14:30:00";
//     //std::string outputDate1 = simple_time::convertTmFormat(inputDate1, simple_time::TM_FORMAT_1, simple_time::TM_FORMAT_2);
//     //std::cout << "Converted date 1: " << outputDate1 << std::endl;
//
//
//     //std::string inputDate2 = "202307241430";
//     //std::string outputDate2 = simple_time::convertTmFormat(inputDate2, simple_time::TM_FORMAT_4, simple_time::TM_FORMAT_5);
//     //std::cout << "Converted date 2: " << outputDate2 << std::endl;
//     //// Output: Converted date 2: 2023-07-24 14:30
//
//
//     //std::string inputDate3 = "2023-07-24 14:00";
//     //std::string outputDate3 = simple_time::convertTmFormat(inputDate3, simple_time::TM_FORMAT_8, simple_time::TM_FORMAT_6);
//     //std::cout << "Converted date 3: " << outputDate3 << std::endl;
//     //// Output: Converted date 3: 20230724
//
//
//     //std::string inputDate4 = "2023-07-24-14-30-00";
//     //std::string outputDate4 = simple_time::convertTmFormat(inputDate4, simple_time::TM_FORMAT_7, simple_time::TM_FORMAT_3);
//     //std::cout << "Converted date 4: " << outputDate4 << std::endl;
//     //// Output: Converted date 4: 14
//
//
//     //return 0;
//
//
//     //std::string path = "D:/1_wangyingjie/readfile/daily snow depth_AMSRE_full/2007_tif";
//     //std::vector<std::string> all_path = studio_file::collectFileOrDirEntries(path);
//
//     //std::string tm = "2024-07-15 10:11";
//     //boost::posix_time::ptime boostTm = simple_time::TimeFromString(tm);
//
//     //std::string format_tm = simple_time::TimeToFormatString(boostTm);
//
//     //return 0;
// }
